home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #11 / Amiga Plus CD - 2002 - No. 11.iso / Tools / Development / Feelin021015 / Examples / Class3.e < prev    next >
Text File  |  2002-10-28  |  7KB  |  220 lines

  1. OPT PREPROCESS
  2.  
  3. MODULE 'intuition/intuition',
  4.        'feelin','libraries/feelin','a4'
  5.  
  6. -> This is the instance data for our custom class.
  7.  
  8. OBJECT mydata
  9.   x:INT,y:INT
  10.   sx:INT,sy:INT
  11. ENDOBJECT
  12.  
  13. PROC main()
  14.    DEF c,w,myobj,
  15.        fcc:PTR TO feelinClass
  16.  
  17.    sys_SGlob()
  18.  
  19.    IF feelinbase := OpenLibrary('feelin.library',FV_VERSION)
  20. /*
  21. Create the new custom class with a call to F_CreateClass().
  22.  
  23. This function returns a feelinClass structure. You  must  use  class.id  to
  24. create  instance  of  your  custom  class.  This  ID  is unique and made by
  25. F_CreateClass() when ID is NIL.
  26. */
  27.  
  28.       IF fcc := F_CreateClassA([FA_SuperID,     FC_Area,
  29.                                 FA_DataSize,    SIZEOF mydata,
  30.                                 FA_Dispatcher,  {myDispatcher},
  31.                                 NIL])
  32.  
  33.          c := ClientObject,
  34.             Child, w := WindowObject, FA_Window_Title, 'A rather complex custom class',
  35.                Child, VGroup,
  36.                   Child, TextObject, FA_FixedHeight,TRUE, DontChain, TextFrame, TextBack, FA_Text, '`c`iPaint `nwith `bmouse`n,\n`iScroll `nwith `bcursor keys`n.', End,
  37.                   Child, myobj := F_NewObjA(fcc.id,[TextFrame, TAG_DONE]),
  38.                End,
  39.  
  40.                FA_Window_ActiveObject, myobj, -> Safe here
  41.             End,
  42.          End
  43.  
  44.          IF c
  45.             F_DoA(w,FM_Notify,[FA_Window_CloseRequest,TRUE, c,2,FM_Client_ReturnID,FV_Client_Quit])
  46.             F_Set(w,FA_Window_Open,TRUE)
  47.  
  48.             F_DoA(c,FM_Client_Run,NIL)
  49.  
  50.             F_DisposeObj(c)
  51.          ENDIF
  52.  
  53.          F_RemoveClass(fcc)
  54.       ELSE
  55.          WriteF('Could not create custom class.\n')
  56.       ENDIF
  57.  
  58.       CloseLibrary(feelinbase)
  59.    ELSE
  60.       WriteF('Failed to open feelin.library\n')
  61.    ENDIF
  62. ENDPROC
  63.  
  64. PROC myDispatcher(cl=A2:PTR TO feelinClass,obj=A0:PTR TO feelinObject,method=D0,args=A1:PTR TO LONG)
  65.    DEF data:PTR TO mydata
  66.  
  67.    sys_RGlob() ; data := INST_DATA(cl,obj)
  68.  
  69. /*
  70. Here comes the dispatcher for our custom class. Unknown/unused methods  are
  71. passed to the superclass immediately.
  72. */
  73.  
  74.    SELECT method
  75.       CASE FM_AskMinMax   ;        mAskMinMax   (cl,obj)
  76.       CASE FM_Draw        ;        mDraw        (cl,obj,data,args)
  77.       CASE FM_HandleEvent ; RETURN mHandleEvent (obj,data,args)
  78.       CASE FM_Active      ;        mActive      (cl,obj,TRUE)
  79.       CASE FM_Inactive    ;        mActive      (cl,obj,FALSE)
  80.       DEFAULT             ; RETURN F_SuperDoA   (cl,obj,method,args)
  81.    ENDSELECT
  82. ENDPROC 
  83. PROC mAskMinMax(cl,obj:PTR TO feelinObject)
  84. /*
  85.    Area.AskMinMax() will be called before the window is opened. We need  to
  86.    tell Feelin the minimum and maximum size of our object.
  87.  
  88.    When you are the first receiving  the  method  the  fields  _minw()  and
  89.    _minh() are set to zero and the fields _maxw() and _maxh() to FV_MAXMAX.
  90.    We can add values to _minw() and _minh() or set _maxw() and  _maxh()  if
  91.    we need to. Then we pass the method to our superclass.
  92.  
  93.    When the method  reaches  Area  class  these  values  will  be  adjusted
  94.    according to FA_MinXxx, FA_FixedXxx and FA_FixXxx attributes.
  95. */
  96.  
  97.    _minw(obj) += 100 ; _minh(obj) += 40
  98.    _maxw(obj) := 500 ; _maxh(obj) := 300
  99.  
  100.    F_SuperDoA(cl,obj,FM_AskMinMax,NIL)
  101. ENDPROC
  102. PROC mDraw(cl,obj:PTR TO feelinObject,data:PTR TO mydata,d:PTR TO FS_Draw)
  103. /*
  104.    Draw method is called whenever Feelin feels (obviously  ;-))  we  should
  105.    render  our object. This usually happens after layout is finished. Note:
  106.    You may only render within the rectangle _mleft(),  _mtop(),  _mwidth(),
  107.    _mheight().
  108. */
  109.  
  110.    DEF rp
  111.  
  112. /*
  113.    Let our superclass draw itself first, Area class  would  e.g.  draw  the
  114.    frame and clear the whole region. What it does exactly depends on flags.
  115. */
  116.  
  117.    F_SuperDoA(cl,obj,FM_Draw,d)
  118.  
  119. /*
  120.    IF FF_Draw_Object isn't set, we shouldn't  draw  anything.  Feelin  just
  121.    wanted to update the frame or something like that.
  122. */
  123.  
  124.    rp := _rp(obj)
  125.  
  126.    IF d.flags AND FF_Draw_Update -> called from our input method
  127.       IF data.sx OR data.sy
  128.          _BPen(_pen(obj,FV_Pen_Shine))
  129.          ScrollRaster(rp,data.sx,data.sy,_mx(obj),_my(obj),_mx2(obj),_my2(obj))
  130.          _BPen(_pen(obj,FV_Pen_Dark))
  131.          data.sx := NIL
  132.          data.sy := NIL
  133.       ELSE
  134.          _APen(_pen(obj,FV_Pen_Shadow))
  135.          _Plot(data.x,data.y)
  136.       ENDIF
  137.    ELSEIF d.flags AND FF_Draw_Object
  138.       _APen(_pen(obj,FV_Pen_Shine))
  139.       _Boxf(_mx(obj),_my(obj),_mx2(obj),_my2(obj))
  140.    ENDIF
  141. ENDPROC
  142. PROC mActive(cl,obj:PTR TO feelinObject,state)
  143. /*
  144.    Area class always creates an EventHandler  structure  in  case  of  some
  145.    inputmodes.  As  we handle events instead of Area class we can use it as
  146.    we want. It will save us some allocations ;-)
  147.  
  148.    Using F_ModifyHandler() to modify IDCMP flags it's a piece  of  cake  to
  149.    request IDCMP events.
  150. */
  151.  
  152.    IF state
  153.       F_DoA(obj,FM_ModifyHandler,[IDCMP_RAWKEY OR IDCMP_MOUSEBUTTONS,NIL])
  154.    ELSE
  155.       F_DoA(obj,FM_ModifyHandler,[NIL,IDCMP_RAWKEY OR IDCMP_MOUSEBUTTONS])
  156.    ENDIF
  157.  
  158.    F_SuperDoA(cl,obj,IF state THEN FM_Active ELSE FM_Inactive,NIL)
  159. ENDPROC
  160. PROC mHandleEvent(obj:PTR TO feelinObject,data:PTR TO mydata,he:PTR TO FS_HandleEvent)
  161. /*
  162. in mSetup() we said that we want get a  message  if  mousebuttons  or  keys
  163. pressed so we have to define the input-handler
  164.  
  165. Note :
  166.  
  167.    This is really a good example, because it  shows  how  to  use  critical
  168.    events carefully:
  169.  
  170.    IDCMP_MOUSEMOVE is only needed when left-mousebutton is pressed,  so  we
  171.    dont  request  this  until  we  get  a  SELECTDOWN-message and we reject
  172.    IDCMP_MOUSEMOVE immeditly after we get a SELECTUP-message
  173. */
  174.  
  175.    #define _between(a,x,b) (x == [a TO b])
  176.    #define _isinobject(x,y) (_between(_mx(obj),(x),_mx2(obj)) AND _between(_my(obj),(y),_my2(obj)))
  177.  
  178. /*
  179. Note on Arrows handling :
  180.  
  181. If you don't handle arrows return NIL, this will  allow  Window  object  to
  182. cycle   through  its  chain  using  arrows  instead  of  tabulations  (more
  183. confortable hu ?), else return your object. Currently, result is only check
  184. against NIL, but this may change in future, so return your object.
  185. */
  186.  
  187.    IF he.key <> FV_KEY_NONE
  188.       SELECT he.key
  189.          CASE FV_KEY_LEFT  ; data.sx := -1
  190.          CASE FV_KEY_RIGHT ; data.sx :=  1
  191.          CASE FV_KEY_UP    ; data.sy := -1
  192.          CASE FV_KEY_DOWN  ; data.sy :=  1
  193.          DEFAULT           ; RETURN NIL
  194.       ENDSELECT
  195.  
  196.       F_Draw(obj,FF_Draw_Update)
  197.  
  198.       RETURN FF_HandleEvent_Eat -> Forbid arrow cycling, because *WE* handle key events.
  199.    ELSEIF he.msg.class = IDCMP_MOUSEBUTTONS
  200.       IF he.msg.code = SELECTDOWN
  201.          IF _isinobject(he.msg.mousex,he.msg.mousey)
  202.             data.x := he.msg.mousex
  203.             data.y := he.msg.mousey
  204.             F_Draw(obj,FF_Draw_Update)
  205.             -> Only request IDCMP_MOUSEMOVE if we realy need it
  206.             F_DoA(obj,FM_ModifyHandler,[IDCMP_MOUSEMOVE,NIL])
  207.          ENDIF
  208.       ELSE
  209.          -> Reject IDCMP_MOUSEMOVE because lmb is no longer pressed
  210.          F_DoA(obj,FM_ModifyHandler,[NIL,IDCMP_MOUSEMOVE])
  211.       ENDIF
  212.    ELSEIF he.msg.class = IDCMP_MOUSEMOVE
  213.       IF _isinobject(he.msg.mousex,he.msg.mousey)
  214.          data.x := he.msg.mousex
  215.          data.y := he.msg.mousey
  216.          F_Draw(obj,FF_Draw_Update)
  217.       ENDIF
  218.    ENDIF
  219. ENDPROC
  220.